home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src / lib / asm / time.s < prev    next >
Encoding:
Text File  |  1998-10-04  |  10.1 KB  |  543 lines

  1. ;
  2. ; time.s -- an ACE linked library module: time and date functions.
  3. ; Copyright (C) 1998 David Benn
  4. ; This program is free software; you can redistribute it and/or
  5. ; modify it under the terms of the GNU General Public License
  6. ; as published by the Free Software Foundation; either version 2
  7. ; of the License, or (at your option) any later version.
  8. ;
  9. ; This program is distributed in the hope that it will be useful,
  10. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ; GNU General Public License for more details.
  13. ;
  14. ; You should have received a copy of the GNU General Public License
  15. ; along with this program; if not, write to the Free Software
  16. ; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17. ;
  18. ; Author: David J Benn
  19. ;   Date: 3rd-30th November, 1st-13th December 1991,
  20. ;      20th, 23rd,25th-27th January 1992, 
  21. ;         2nd,4th,6th,12th-19th,21st-24th,29th February 1992,
  22. ;      1st,14th March 1992,
  23. ;      4th,7th,21st,22nd,26th April 1992,
  24. ;      2nd,3rd,5th,7th,8th,10th-17th May 1992,
  25. ;      6th,8th,11th,12th,28th,30th June 1992,
  26. ;      1st-3rd,13th,14th,18th-20th,22nd July 1992,
  27. ;      9th August 1992,
  28. ;      5th December 1992,
  29. ;      1st March 1993,
  30. ;      19th March 1994
  31. ;
  32. ; registers d0-d6 and a0-a3 are modified by some of the following. BEWARE!
  33. ;
  34. ; a4,a5 are used by link/unlk.
  35. ; a6 is library base holder.
  36. ; a7 is stack pointer. 
  37. ; d7 is used for array index calculations.
  38. ;
  39.  
  40. ; misc. defines
  41. MAXSTRINGSIZE    EQU    1024
  42.  
  43.        ; time and date functions
  44.     xdef    _timeofday
  45.     xdef    _date
  46.     xdef    _getday
  47.     xdef    _timer
  48.     xdef    _ontimerstart
  49.      xdef    _ontimer
  50.     
  51.        ; external references 
  52.      xref    _shortfmt
  53.     xref    _longfmt
  54.  
  55.     xref    _sprintf
  56.      xref      _DOSBase
  57.     xref    _LVODateStamp    
  58.     xref    _strcat
  59.     xref    _strcpy
  60.     xref    _MathBase
  61.     xref    _LVOSPFlt
  62.     xref    _LVOSPAdd
  63.     xref    _LVOSPMul
  64.     xref    _LVOSPDiv
  65.     xref    _LVOSPCmp
  66.     
  67.     SECTION time_code,CODE
  68.  
  69. ;*** TIME and DATE FUNCTIONS ***
  70.  
  71. ;
  72. ; TIME$ - returns a pointer to a string containing the time in hh:mm:ss format
  73. ;      in d0.
  74. ;
  75. _timeofday:
  76.     move.l    #_datestampholder,d1
  77.     movea.l    _DOSBase,a6
  78.     jsr    _LVODateStamp(a6)
  79.     lea    _datestampholder,a1
  80.  
  81.     move.l    4(a1),d0
  82.     divu    #60,d0
  83.     move.w    d0,_todhrs        ; hours = 0..23
  84.  
  85.     swap    d0
  86.     move.w    d0,_todmins        ; minutes = 0..59
  87.  
  88.     move.l    8(a1),d0
  89.     divu    #50,d0
  90.     move.w    d0,_todsecs        ; seconds = 0..59
  91.  
  92.     move.w    _todhrs,-(sp)
  93.     pea    _shortfmt
  94.     pea    _todhrstr
  95.     jsr    _sprintf
  96.     add.l    #10,sp            ; hours to string
  97.  
  98.     move.w    _todmins,-(sp)
  99.     pea    _shortfmt
  100.     pea    _todminstr
  101.     jsr    _sprintf
  102.     add.l    #10,sp            ; minutes to string
  103.  
  104.     move.w    _todsecs,-(sp)
  105.     pea    _shortfmt
  106.     pea    _todsecstr
  107.     jsr    _sprintf
  108.     add.l    #10,sp            ; seconds to string
  109.  
  110.     lea    _tmpstring,a2
  111.     move.b    #0,(a2)        ; EOS for _strcat
  112.  
  113.     cmpi.w    #10,_todhrs
  114.     bge.s    _concathrs
  115.     lea    _zerostr,a1
  116.     movea.l    a2,a0        
  117.     jsr    _strcat            ; concatenate hours to tod string
  118. _concathrs:
  119.     lea    _todhrstr,a1
  120.     movea.l    a2,a0
  121.     jsr    _strcat
  122.  
  123.     lea    _colonstr,a1
  124.     movea.l    a2,a0
  125.     jsr    _strcat            ; colon in hh:mm
  126.  
  127.     cmpi.w    #10,_todmins
  128.     bge.s    _concatmins
  129.     lea    _zerostr,a1
  130.     movea.l    a2,a0        
  131.     jsr    _strcat            ; concatenate minutes to tod string
  132. _concatmins:
  133.     lea    _todminstr,a1
  134.     movea.l    a2,a0
  135.     jsr    _strcat
  136.  
  137.     lea    _colonstr,a1
  138.     movea.l    a2,a0
  139.     jsr    _strcat            ; colon in mm:ss
  140.     
  141.     cmpi.w    #10,_todsecs
  142.     bge.s    _concatsecs
  143.     lea    _zerostr,a1
  144.     movea.l    a2,a0        
  145.     jsr    _strcat            ; concatenate seconds to tod string
  146. _concatsecs:
  147.     lea    _todsecstr,a1
  148.     movea.l    a2,a0
  149.     jsr    _strcat
  150.     
  151.     movea.l    a2,a1
  152.     lea    _timestring,a0
  153.     jsr    _strcpy            ; copy temp string to tod string
  154.  
  155.     move.l    #_timestring,d0        ; address in d0
  156.  
  157.     rts
  158.  
  159. ;
  160. ; DATE$ - returns pointer to a string containing the date in mm-dd-yyyy format
  161. ;       in d0. See rwm.c year_and_month() function.
  162. ;
  163. _date:
  164.     ; initialise year, month and day of week
  165.       move.l    #1978,_year
  166.     move.l    #1,_month
  167.     move.l    #0,_day_of_week
  168.  
  169.     ; get days
  170.     move.l    #_datestampholder,d1
  171.     movea.l    _DOSBase,a6
  172.     jsr    _LVODateStamp(a6)
  173.     lea    _datestampholder,a1
  174.     move.l    (a1),_days
  175.  
  176.     ; find the year
  177. _find_year:
  178.     cmpi.l    #365,_days
  179.     ble    _modify_feb    ; days > 365? -> continue finding year
  180.     
  181.     ; leap year?
  182.     move.l    _year,d0
  183.     jsr    _leap_year_check
  184.     cmpi.b    #0,d0
  185.     beq.s    _no_leap_year
  186.  
  187.     ; decrement days by 366
  188.     subi.l    #366,_days
  189.  
  190.     ; update day of week
  191.     move.l    #366,d1
  192.     jsr    _change_day_of_week
  193.  
  194.     ; increment year
  195.     addi.l    #1,_year
  196.     bra    _find_year
  197.     
  198.  _no_leap_year:
  199.     ; decrement days by 365
  200.     subi.l    #365,_days
  201.  
  202.     ; update day of week
  203.     move.l    #365,d1
  204.     jsr    _change_day_of_week
  205.     
  206.     ; increment year
  207.     addi.l    #1,_year
  208.     bra    _find_year
  209.  
  210.     ; calculate month
  211. _modify_feb:
  212.     ; get address of february day holder
  213.     move.l    #_days_in_month,d0
  214.     add.l    #2,d0
  215.     move.l    d0,a0
  216.  
  217.     ; default is 28 days
  218.     move.w    #28,(a0)
  219.  
  220.     ; leap year?
  221.     move.l    _year,d0
  222.     jsr    _leap_year_check
  223.     cmpi.b    #0,d0
  224.     beq.s    _find_month
  225.  
  226.     ; add a leap day
  227.     move.w    #29,(a0)
  228.  
  229. _find_month:
  230.     jsr    _days_in_this_month
  231.     move.l    _days,d1
  232.     cmp.l    d0,d1        ; days (d1) > days in this month (d0) ?
  233.     ble.s    _adjust_day_and_month
  234.  
  235.     ; decrement # of days
  236.     jsr    _days_in_this_month
  237.     sub.l    d0,_days    ; days -= days in this month
  238.     
  239.     ; update day of week
  240.     move.l    d0,d1        ; d1 = days in this month
  241.     jsr    _change_day_of_week
  242.  
  243.     ; increment month
  244.     addi.l    #1,_month    ; month++
  245.     bra.s    _find_month
  246.  
  247. _adjust_day_and_month:
  248.     ; final day of week update
  249.     move.l    _days,d1
  250.     jsr    _change_day_of_week
  251.  
  252.     cmpi.l    #2000,_year    ; year < 2000?
  253.     bge.s    _adjust_day_month
  254.     addi.l    #1,_days    ; days++
  255.  
  256. _adjust_day_month:
  257.     jsr    _days_in_this_month
  258.     move.l    _days,d1
  259.     cmp.l    d0,d1        ; days (d1) > days in this month (d0) ?
  260.     ble.s    _adjust_month_and_year
  261.     move.l    #1,_days    ; days=1
  262.     addi.l    #1,_month    ; month++
  263.  
  264. _adjust_month_and_year:
  265.     cmpi.l    #13,_month    ; month=13 ?
  266.     bne.s    _construct_datestring
  267.     move.l    #1,_month    ; month=1
  268.     addi.l    #1,_year    ; year++
  269.  
  270. _construct_datestring:
  271.     ; convert days,month,year to strings
  272.     move.l    #_daystr,d1
  273.     cmpi.l    #10,_days    ; days < 10?
  274.     bge.s    _makedaystring
  275.     ; '0' prefix
  276.     move.l    d1,a0
  277.     move.b    #48,(a0)
  278.     add.l    #1,d1        ; add 1 to start posn in day string
  279.  
  280. _makedaystring:
  281.     move.l    _days,-(sp)
  282.     pea    _longfmt
  283.     move.l    d1,-(sp)    ; address of day string
  284.     jsr    _sprintf
  285.     add.l    #12,sp
  286.  
  287.     ; month string (as for days)
  288.     move.l    #_monthstr,d1
  289.     cmpi.l    #10,_month    ; month < 10 ?
  290.     bge.s    _makemonthstring
  291.     ; '0' prefix
  292.     move.l    d1,a0
  293.     move.b    #48,(a0)
  294.     add.l    #1,d1
  295.  
  296. _makemonthstring:
  297.     move.l    _month,-(sp)
  298.     pea    _longfmt
  299.     move.l    d1,-(sp)
  300.     jsr    _sprintf
  301.     add.l    #12,sp
  302.  
  303.     ; year string
  304.     move.l    _year,-(sp)
  305.     pea    _longfmt
  306.     pea    _yearstr
  307.     jsr    _sprintf
  308.     add.l    #12,sp
  309.  
  310.     ; build whole date string
  311.     lea    _tmpstring,a0
  312.     move.b    #0,(a0)        ; EOS for _strcat
  313.  
  314.     ; month
  315.     lea    _tmpstring,a0
  316.     lea    _monthstr,a1
  317.     jsr    _strcat        ; MM
  318.  
  319.     lea    _tmpstring,a0
  320.     lea    _dash,a1
  321.     jsr    _strcat        ; '-'
  322.  
  323.     ; day
  324.     lea    _tmpstring,a0
  325.     lea    _daystr,a1
  326.     jsr    _strcat        ; DD
  327.  
  328.     lea    _tmpstring,a0
  329.     lea    _dash,a1
  330.     jsr    _strcat        ; '-'
  331.  
  332.     ; year
  333.     lea    _tmpstring,a0
  334.     lea    _yearstr,a1
  335.     jsr    _strcat        ; YYYY
  336.  
  337.     lea    _datestring,a0
  338.     lea    _tmpstring,a1
  339.     jsr    _strcpy
  340.  
  341.     move.l    #_datestring,d0
  342.         
  343.     rts    
  344.  
  345. ;
  346. ; Leap Year? d0=year. Returns 0 or -1 in d0.
  347. ;
  348. _leap_year_check:
  349.     ; divisible by 4?
  350.     move.l    d0,d1
  351.     divu    #4,d1
  352.     swap    d1
  353.     cmpi.w    #0,d1
  354.     beq.s    _check100
  355.     bra    _quitleapyearcheck
  356.  
  357.     ; divisible by 100?
  358. _check100:
  359.     move.l    d0,d1
  360.     divu    #100,d1
  361.     swap    d1
  362.     cmpi.w    #0,d1
  363.     beq.s    _check400
  364.     move.b    #-1,d0        ; leap year
  365.     rts
  366.     
  367. _check400:
  368.     move.l    d0,d1
  369.     divu    #400,d1
  370.     swap     d1
  371.     cmpi.w    #0,d1
  372.     bne.s    _quitleapyearcheck
  373.     move.b    #-1,d0        ; leap year
  374.     rts
  375.  
  376. _quitleapyearcheck:
  377.     move.b    #0,d0        ; not a leap year
  378.     rts
  379.  
  380. ;
  381. ; Return # of days in this month.
  382. ;
  383. _days_in_this_month:
  384.     move.l    _month,d0
  385.     sub.l    #1,d0
  386.     lsl.l    #1,d0        ; index *= 2
  387.     move.l    #_days_in_month,d1
  388.     add.l    d0,d1
  389.     move.l    d1,a0
  390.     move.w    (a0),d0        ; days_in_month[month-1]
  391.     ext.l    d0        
  392.  
  393.     rts
  394.  
  395. ;
  396. ; Update the day of week to be within the range 0..6. 
  397. ;
  398. _change_day_of_week:
  399.     move.l    _day_of_week,d0
  400.     add.l    d1,d0
  401.     divu    #7,d0
  402.     swap    d0
  403.     ext.l    d0
  404.     move.l    d0,_day_of_week    
  405.     rts
  406.  
  407. ;
  408. ; Return day of week in d0 as a number from 0..6 where 0=Sunday.
  409. ; DATE$ must be called first to update _day_of_week variable.
  410. ;
  411. _getday:
  412.     move.l    _day_of_week,d0
  413.     rts
  414.  
  415. ;
  416. ; TIMER - returns a single-precision value in d0 corresponding to seconds 
  417. ;         elapsed since midnight. 
  418. ;
  419. _timer:
  420.     move.l    #_datestampholder,d1
  421.     movea.l    _DOSBase,a6
  422.     jsr    _LVODateStamp(a6)
  423.     lea    _datestampholder,a1            
  424.  
  425.     movea.l    _MathBase,a6
  426.  
  427.     move.l    4(a1),d0        
  428.     jsr    _LVOSPFlt(a6)        
  429.     move.l    d0,_mins        ; minutes since midnight
  430.  
  431.     move.l    8(a1),d0
  432.     jsr    _LVOSPFlt(a6)
  433.     move.l    d0,_ticks        ; ticks in current minute
  434.  
  435.     move.l    _mins,d0        
  436.     move.l    #$f0000046,d1        ; ffp 60
  437.     jsr    _LVOSPMul(a6)        ; seconds since midnight (_mins*60)
  438.     move.l    d0,_minsecs
  439.  
  440.     move.l    _ticks,d0        
  441.     move.l    #$c8000046,d1        ; ffp 50 (50 ticks per sec)
  442.     jsr    _LVOSPDiv(a6)        ; seconds in current minute (_ticks/50)
  443.     move.l    d0,_ticksecs
  444.     
  445.     move.l    _minsecs,d0
  446.     move.l    _ticksecs,d1
  447.     jsr    _LVOSPAdd(a6)        ; total seconds elapsed since
  448.                     ; midnight including current minute
  449.     rts
  450.             
  451. ;
  452. ; Initialises timer event trapping with a start time. 
  453. ;
  454. _ontimerstart:
  455.     jsr    _timer
  456.     move.l    d0,_last_time    
  457.     rts
  458.  
  459. ;
  460. ; Determines whether a timer event is due. d0=timer event interval.
  461. ; A boolean result is returned in d0. 
  462. ;
  463. _ontimer:
  464.     ; calculate target time
  465.     movea.l    _MathBase,a6
  466.     move.l    _last_time,d1
  467.     jsr    _LVOSPAdd(a6)
  468.     move.l    d0,_target_time    ; target_time = last_time + interval
  469.  
  470.     ; get current time
  471.     jsr    _timer    
  472.     move.l    d0,_curr_time    ; store current time
  473.  
  474.     ; is an event due?
  475.     movea.l    _MathBase,a6
  476.     move.l    _target_time,d1    
  477.     jsr    _LVOSPCmp(a6)    ; curr_time (d0) >= target_time (d1)?
  478.     bge.s    _target_time_reached
  479.  
  480.     moveq    #0,d0        ; timer event NOT due
  481.     rts
  482.  
  483. _target_time_reached:
  484.     ; update last time an event occurred
  485.     move.l    _curr_time,_last_time
  486.  
  487.     moveq    #-1,d0        ; timer event due
  488.     rts
  489.  
  490. ;*****************************
  491.  
  492.     SECTION time_data,DATA
  493.  
  494. ; * general *
  495. _zerostr:    dc.b '0',0
  496. _colonstr:    dc.b ':',0
  497.  
  498. ; * date *
  499. _dash:         dc.b '-',0
  500. _days_in_month: dc.w 31,28,31,30,31,30,31,31,30,31,30,31
  501.  
  502. ; *************************
  503.  
  504.     SECTION time_mem,BSS
  505.  
  506. ; * general *
  507. _tmpstring:            ds.b MAXSTRINGSIZE
  508. _datestampholder:    ds.l 3
  509.  
  510. ; * timeofday *
  511. _tmpaddr:        ds.l 1
  512. _todhrs:        ds.w 1
  513. _todmins:        ds.w 1
  514. _todsecs:        ds.w 1
  515. _todhrstr:        ds.b 3
  516. _todminstr:        ds.b 3
  517. _todsecstr:        ds.b 3
  518. _timestring:        ds.b 9
  519.  
  520. ; * date *
  521. _days:            ds.l 1
  522. _month:            ds.l 1
  523. _year:            ds.l 1
  524. _daystr:        ds.b 3
  525. _monthstr:        ds.b 3
  526. _yearstr:        ds.b 5
  527. _datestring:        ds.b 11
  528. _day_of_week:        ds.l 1
  529.  
  530. ; * timer *
  531. _mins:            ds.l 1
  532. _ticks:            ds.l 1
  533. _minsecs:        ds.l 1
  534. _ticksecs:        ds.l 1
  535.  
  536. ; * ontimer *
  537. _last_time:        ds.l 1
  538. _curr_time:        ds.l 1
  539. _target_time:        ds.l 1
  540.  
  541.     END
  542.